home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
exampleCode
/
stencil
/
outline.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
7KB
|
275 lines
/*
* Copyright 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/* outline.c
* outline.c draws two outlined rotating torii .
*/
#include <gl/gl.h>
#include <gl/device.h>
#include <stdio.h>
#include <math.h>
void def_simple_light_calc(void);
void use_simple_light_calc(void);
void main(void);
void initialize(void);
void drawscene(void);
float shiny_material[] = {
DIFFUSE, 0.4, 0.4, 0.4,
SPECULAR, 1.0, 1.0, 1.0,
SHININESS, 128.0,
LMNULL };
float blue_material[] = {
DIFFUSE, 0.0, 0.0, 0.4,
SPECULAR, 0.0, 1.0, 1.0,
SHININESS, 45.0,
LMNULL };
void
def_simple_light_calc(void)
{
lmdef(DEFMATERIAL, 1, 11, shiny_material);
lmdef(DEFMATERIAL, 2, 11, blue_material);
lmdef(DEFLIGHT, 1, 0, NULL);
lmdef(DEFLMODEL, 1, 0, NULL);
}
void
use_simple_light_calc(void)
{
lmbind(LIGHT0, 1);
lmbind(LMODEL, 1);
}
/* three dimensional vector */
typedef float vector[3];
/* number of polygons around the cross section of the torus */
#define TORUS_NUMC 10
/* number of polygons around the outside of the torus */
#define TORUS_NUMT 20
/* default torus cross sectional radius */
#define TORUS_RAD_XC 0.3
/* default torus radius */
#define TORUS_RAD 1.0
/* arrays for torus vertices and normals */
static vector torus_point[TORUS_NUMC][TORUS_NUMT];
static vector torus_norm[TORUS_NUMC][TORUS_NUMT];
/* has the torus been initialized yet */
static Boolean torus_initialized = FALSE;
/* initalize data for a torus */
static void inittorus(
float rc, /* radius of the cross section */
float rt, /* radius of the torus */
vector point[TORUS_NUMC][TORUS_NUMT], /* array of vertices */
vector norm[TORUS_NUMC][TORUS_NUMT]) /* array of normals */
{
int i, j;
int numc = TORUS_NUMC, numt = TORUS_NUMT;
float twopi, fi, fj, xc, yc, nx, ny, nz, n;
twopi = 2.0 * M_PI;
/* go around cross section */
for (i = 0; i < numc; i++) {
fi =(float) i;
/* go around top view */
for (j = 0; j < numt; j++) {
fj =(float) j;
point[i][j][0] = (rt + rc*fcos(twopi * fi/numc))
* fcos(twopi * fj/numt);
point[i][j][1] = (rt + rc*fcos(twopi * fi/numc))
* fsin(twopi * fj/numt);
point[i][j][2] = rc * fsin(twopi * fi/numc);
xc = rt*fcos(twopi*fj/numt);
yc = rt*fsin(twopi*fj/numt);
nx = point[i][j][0] - xc;
ny = point[i][j][1] - yc;
nz = point[i][j][2];
n = fsqrt(nx*nx + ny*ny + nz*nz);
norm[i][j][0] = nx/n;
norm[i][j][1] = ny/n;
norm[i][j][2] = nz/n;
}
}
}
/* set the cross sectional and torus radius */
void settorus(float rc, float rt)
{
inittorus(rc,rt,torus_point,torus_norm);
torus_initialized = TRUE;
}
/* filled torus */
void ftorus(void)
{
int i, j;
int numc = TORUS_NUMC, numt = TORUS_NUMT;
if (! torus_initialized)
settorus(TORUS_RAD_XC,TORUS_RAD);
for (i = 0; i < numc; i++) {
bgntmesh();
n3f(torus_norm[(i+1)%numc][0]);
v3f(torus_point[(i+1)%numc][0]);
for (j = 0; j < numt; j++) {
n3f(torus_norm[i][j]);
v3f(torus_point[i][j]);
n3f(torus_norm[(i+1)%numc][(j+1)%numt]);
v3f(torus_point[(i+1)%numc][(j+1)%numt]);
}
n3f(torus_norm[i][0]);
v3f(torus_point[i][0]);
endtmesh();
}
}
void
main(void)
{
short attached;
short value;
int dev;
attached = 1;
if (!getgdesc(GD_POLYMODE)) {
fprintf(stderr, "This machine does not support polymode.\n");
exit(0);
}
initialize();
while (TRUE) {
while (qtest() || !attached) {
dev = qread (&value);
if ((dev == ESCKEY) && (value == 0))
exit(0);
else if (dev == REDRAW) {
reshapeviewport();
drawscene();
}
else if (dev == INPUTCHANGE)
attached = value;
} /* end while qtest or not attached */
drawscene();
} /* end while (TRUE) */
} /* end main() */
/* The initialize subroutine positions the window and specifies
* its future constraints. The program is in double buffer
* and RGB mode. The simplest lighting model is used.
*/
void
initialize(void)
{
long gid1;
long xmax, ymax;
xmax = getgdesc(GD_XPMAX);
ymax = getgdesc(GD_YPMAX);
prefposition( xmax/4, xmax*3/4, ymax/4, ymax*3/4 );
gid1 = winopen ("outline");
minsize (xmax/10, ymax/10);
keepaspect (xmax, ymax);
winconstraints();
doublebuffer();
RGBmode();
stensize ( 1 );
gconfig();
zbuffer(TRUE);
subpixel(TRUE);
qdevice (ESCKEY);
qenter (REDRAW, gid1);
mmode(MVIEWING);
perspective( 450, (float)xmax/(float)ymax, 3.0, 7.0);
lookat(2.5, 0.0, 5.0, 0.0, 0.0, 0.0, 0);
def_simple_light_calc();
use_simple_light_calc();
}
/* Draw 2 outlined rotating torii
*/
void
drawscene(void)
{
static Angle angle = 0; /* counter for angle rotation */
czclear(0x0, getgdesc(GD_ZMAX));
/* draw them filled */
polymode( PYM_FILL );
pushmatrix();
rotate(angle * 2, 'z');
rotate(angle * 2, 'y');
lmbind(MATERIAL,1);
ftorus();
pushmatrix();
rotate(900, 'x');
ftorus();
popmatrix();
popmatrix();
/* draw them hollow */
sclear(0x0); /* for PYM_HOLLOW */
stencil (TRUE, 1, SF_EQUAL, 0x1, ST_KEEP, ST_KEEP, ST_REPLACE);
polymode( PYM_HOLLOW );
pushmatrix();
rotate(angle * 2, 'z');
rotate(angle * 2, 'y');
lmbind(MATERIAL,2);
ftorus();
pushmatrix();
rotate(900, 'x');
ftorus();
popmatrix();
popmatrix();
stencil (FALSE, 1, SF_EQUAL, 0x1, ST_KEEP, ST_KEEP, ST_REPLACE);
swapbuffers();
angle = angle + 10;
}